/*
 * @Author: secrets123
 * @Date: 2022-07-21 10:53:28
 * @LastEditors: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
 * @LastEditTime: 2023-11-24 14:29:27
 * @FilePath: \stm32g431_AllRings\applications\allrings_sys.c
 * @Description:
 *
 * Copyright (c) 2022 by secrets123 1097290967@qq.com, All Rights Reserved.
 */
#include <rtthread.h>
#include <rtconfig.h>
#include <board.h>
#include "version.h"
#include "allrings_sys.h"
#include "srt_im.h"
#include "epg_xx.h"
#include "ws2812.h"
#include "iap_para.h"
#include "soft_iic.h"
#include "rs485.h"
#include "fdcan_app.h"

#define DBG_TAG "allrings_sys"
#define DBG_LVL DBG_ERROR // DBG_INFO
#include <rtdbg.h>

#define RS485_SET_PIN GET_PIN(B, 11) // 匹配电阻使能
/*thread*/
#define THREAD_STACK_ALLMONITOR 512
#define THREAD_PRIO_ALLMONITOR 11
rt_thread_t allrings_monitor = RT_NULL;
/***************************************万能环外挂设备 相关控制接口注册**************************************/
// union union_sys_savepara allrings_paras; // 万能环系统存储参数

struct _ALLRINGS_CTR rings_ctr =
    {
        .allrings_values.sys_mode = 0x01,
        .allrings_values.can_res_sta = 0x01,   // 默认开启
        .allrings_values.rs485_res_sta = 0x00, // 默认关闭
        ._srt_ctr = &srt_im,
        ._epg_ctr_p = &epg_xx,
        .can_sysback_data = fdcan_sysback_data,
};

/********************************************************************************************************/
void fdcan_sysback_data(struct _fdcan_rxdata *fdcandata)
{
    FDCAN_Transmit(&hfdcan1, fdcandata->id, fdcandata->dta_length, fdcandata->data);
}
// 万能环上挂载的设备控制处理
void allrings_device_ctr(struct _ALLRINGS_CTR *allringctr, union union_sys_savepara *sys_para, struct _fdcan_rxdata *fd_data)
{
    uint8_t cmd_judge_sta = 0; // 指令判断状态，默认为非法
    uint8_t cmd;
    cmd = fd_data->data[0];

    switch ((enum _RINGS_DEVICE_LIST)sys_para->allsys_para.rings_devices)
    {
    case RINGS_NO_DEVICE:
        allringctr->allrings_values.allsys_err.bit.NO_DEVICE = 1; // 上报系统无挂载设备
        break;

    case RINGS_RS485_SRT_IM:
        if (allringctr->_srt_ctr != NULL && allringctr->allrings_values.analaysis_data_type == RB_DATA_BUSY)
        {
            cmd_judge_sta = allringctr->_srt_ctr->inputcmd_valid_check(cmd); // 判断指令是否注册过
            if (cmd_judge_sta)                                               // 指令合法，才允许处理，否则会因为未注册导致程序崩溃
            {
                memcpy(&allringctr->_srt_ctr->fdcan_fdback, fd_data, sizeof(struct _fdcan_rxdata)); // 获取结构体数据
                allringctr->_srt_ctr->device_cmd_srtim[cmd](allringctr->_srt_ctr);                  // 处理启动夹爪
            }
        }
        break;
    case RINGS_RS485_EPG_XX:
        if (allringctr->_epg_ctr_p != NULL && allringctr->allrings_values.analaysis_data_type == RB_DATA_BUSY)
        {
            cmd_judge_sta = allringctr->_epg_ctr_p->inputcmd_valid_check(cmd);      // 判断指令是否注册过,指令合法，才允许处理，否则会因为未注册导致程序崩溃
            if (cmd_judge_sta && (allringctr->allrings_values.allsys_err.Byt == 0)) // 无故障，才允许执行
            {
                memcpy(&allringctr->_epg_ctr_p->fdcan_fdback, fd_data, sizeof(struct _fdcan_rxdata)); // 获取结构体数据
                allringctr->_epg_ctr_p->device_cmd_epg[cmd](allringctr->_epg_ctr_p);                  // 处理启动夹爪
            }
        }
        else // 没数据时，对epg作状态监控处理
        {
            epg_xx_main_ctr(allringctr->_epg_ctr_p);
        }
        break;
    default:
        break;
    }
}
// 万能环系统指令控制与解析
void upper_candata2modbus_analysis(struct _ALLRINGS_CTR *allringctr, struct _fdcan_rxdata *fd_data)
{
    uint8_t cmd;
    // struct _fdcan_rxdata *new_fdcan_data = fd_data;
    // if (fd_data == NULL)
    // {
    //     return;
    // }
    // else
    // {
    //     cmd = fd_data->data[0];
    //     switch (cmd) // 请求对应的设备
    //     {
    //     case ALLRINGS_SYS_READ_HANDSHAKE:
    //         allrings_sys_r_handshake(allringctr, fd_data);
    //         break;
    //     case ALLRINGS_SYS_READ_SWVERSION:
    //         allrings_sys_r_swversion(allringctr, fd_data);
    //         break;
    //     case ALLRINGS_SYS_READ_ADDRS:
    //         allrings_sys_r_addrs(allringctr, fd_data);
    //         break;
    //     case ALLRINGS_SYS_SET_MODE:
    //         allrings_sys_w_mode(allringctr, fd_data);
    //         break;
    //     case ALLRINGS_SYS_READ_MODE:
    //         allrings_sys_r_mode(allringctr, fd_data);
    //         break;
    //     case ALLRINGS_SYS_SET_SAVEPARA:
    //         allrings_sys_w_savedpara(allringctr, fd_data);
    //         break;
    //     case ALLRINGS_SYS_SET_SWITCH:
    //         allrings_sys_w_switch(allringctr, fd_data);
    //         break;
    //     case ALLRINGS_SYS_READ_SWITCH:
    //         allrings_sys_r_switch(allringctr, fd_data);
    //         break;
    //     case ALLRINGS_SYS_SET_CANID:
    //         allrings_sys_w_canid(allringctr, fd_data);
    //         break;
    //     case ALLRINGS_SYS_SET_FDCANINDEX:
    //         allrings_sys_w_fdcanindex(allringctr, fd_data);
    //         break;
    //     case ALLRINGS_SYS_READ_FDCANINDEX:
    //         allrings_sys_r_fdcanindex(allringctr, fd_data);
    //         break;
    //     case ALLRINGS_SYS_READ_HWVERSION:
    //         allrings_sys_r_hwversion(allringctr, fd_data);
    //         break;
    //     case ALLRINGS_SYS_SET_IAP_FLAG:
    //         allrings_sys_w_iap(allringctr, fd_data);
    //         break;
    //     case ALLRINGS_SYS_SET_CLEAR:
    //         allrings_sys_w_clear(allringctr, fd_data);
    //         break;
    //     case ALLRINGS_SYS_READ_ERR:
    //         allrings_sys_r_err(allringctr, fd_data);
    //         break;
    //     default: // 除系统指令之外的挂载设备指令
    //         allrings_device_ctr(allringctr, &allrings_paras, fd_data);
    //         break;
    //     }
    // }
}

/***************************万能环系统监测线程**********************/
void allrgsmonitor_main_entry(void *parameter)
{
    while (1)
    {
        if (rings_ctr.allrings_values.allsys_err.Byt)
        {
            wsled_ctr.blink_times = 1;
            wsled_ctr.user_rgb = WS2812_RGB_RED;
        }
        else
        {
            wsled_ctr.blink_times = 5;
            wsled_ctr.user_rgb = WS2812_RGB_BLUE;
        }
        rt_thread_mdelay(500);
    }
}
int allrings_sysmonitor(void)
{
    /*	create  thread    */
    allrings_monitor = rt_thread_create("all_moni", allrgsmonitor_main_entry, RT_NULL,
                                        THREAD_STACK_ALLMONITOR, THREAD_PRIO_ALLMONITOR, 50);

    if (allrings_monitor == RT_NULL)
    {
        LOG_E("allrings_monitor thread create failed! \r\n");
        return RT_ERROR;
    }
    else
        rt_thread_startup(allrings_monitor); // 启动线程

    return RT_EOK;
}
INIT_APP_EXPORT(allrings_sysmonitor);

/*******************************万能环系统功能接口注册**********************************************/
// 万能环握手
void allrings_sys_r_handshake(struct _ALLRINGS_CTR *allctr, struct _fdcan_rxdata *fd_data)
{
    fd_data->data[1] = 0x01;
    fd_data->dta_length = 2;
    allctr->can_sysback_data(fd_data);
}
// 读软件版本
void allrings_sys_r_swversion(struct _ALLRINGS_CTR *allctr, struct _fdcan_rxdata *fd_data)
{
    uint8_t num = 1;
    fd_data->data[num++] = MAIN_VERSION;
    fd_data->data[num++] = SUB_VERSION;
    fd_data->data[num++] = RE_VERSION;
    fd_data->dta_length = num;
    allctr->can_sysback_data(fd_data);
}
// 读地址信息
void allrings_sys_r_addrs(struct _ALLRINGS_CTR *allctr, struct _fdcan_rxdata *fd_data)
{
    uint8_t num = 1;
    fd_data->data[num++] = 0x00;
    fd_data->data[num++] = 0x03;
    fd_data->data[num++] = 0x12;
    fd_data->data[num++] = 0x34;
    fd_data->data[num++] = 0x56;
    fd_data->data[num++] = 0x78;
    fd_data->dta_length = num;
    allctr->can_sysback_data(fd_data);
}
// 读硬件版本
void allrings_sys_r_hwversion(struct _ALLRINGS_CTR *allctr, struct _fdcan_rxdata *fd_data)
{
    uint8_t num = 1;
    fd_data->data[num++] = ALLRINGS_H_VERSION;
    fd_data->data[num++] = ALLRINGS_H_SUBVERSION;
    fd_data->data[num++] = ALLRINGS_H_REVISION;
    fd_data->dta_length = num;
    allctr->can_sysback_data(fd_data);
}
// 查询万能环设备对象
void allrings_sys_r_device(struct _ALLRINGS_CTR *allctr, struct _fdcan_rxdata *fd_data)
{
    fd_data->data[1] = allrings_paras.allsys_para.rings_devices;
    fd_data->dta_length = 2;
    allctr->can_sysback_data(fd_data);
}
// 保存参数
void allrings_sys_w_savedpara(struct _ALLRINGS_CTR *allctr, struct _fdcan_rxdata *fd_data)
{
    fd_data->data[1] = 0x01;
    fd_data->dta_length = 2;
    allctr->can_sysback_data(fd_data);
    // 发生信号量，通知存储线程进行
    extern rt_sem_t sem_saved;
    rt_sem_release(sem_saved);
}
// 读系统模式
void allrings_sys_r_mode(struct _ALLRINGS_CTR *allctr, struct _fdcan_rxdata *fd_data)
{
    fd_data->data[1] = rings_ctr.allrings_values.sys_mode;
    fd_data->dta_length = 2;
    allctr->can_sysback_data(fd_data);
}
// 设置系统模式
void allrings_sys_w_mode(struct _ALLRINGS_CTR *allctr, struct _fdcan_rxdata *fd_data)
{
    rings_ctr.allrings_values.sys_mode = fd_data->data[1];

    // 反馈设置成功
    fd_data->data[1] = 0x01;
    fd_data->dta_length = 2;
    allctr->can_sysback_data(fd_data);
}

// 设置挂载设备
// void allrings_sys_w_device(struct _ALLRINGS_CTR *allctr, struct _fdcan_rxdata *fd_data)
//{
//    fd_data->data[1] = allrings_paras.allsys_para.rings_devices;
//    fd_data->dta_length = 2;
//    allctr->can_sysback_data(fd_data);
//}

void allrings_sys_w_device(struct _ALLRINGS_CTR *allctr, struct _fdcan_rxdata *fd_data)
{
    uint8_t device;
    device = fd_data->data[1]; // 获取设备名
    if (device == 0x11 || device == 0x12)
    {
        allrings_paras.allsys_para.rings_devices = device;

        fd_data->data[1] = 0x01;
        fd_data->dta_length = 2;
        allctr->can_sysback_data(fd_data);
        // 发生信号量，通知存储线程进行
        extern rt_sem_t sem_saved;
        rt_sem_release(sem_saved);
    }
    else
    {
        fd_data->data[1] = 0x00;
        fd_data->dta_length = 2;
        allctr->can_sysback_data(fd_data);
    }
}

// 查询万能环设备开关
void allrings_sys_r_switch(struct _ALLRINGS_CTR *allctr, struct _fdcan_rxdata *fd_data)
{
    fd_data->data[1] = allctr->allrings_values.all_switch;
    fd_data->dta_length = 2;
    allctr->can_sysback_data(fd_data);
}
void allrings_sys_w_switch(struct _ALLRINGS_CTR *allctr, struct _fdcan_rxdata *fd_data)
{
    allctr->allrings_values.all_switch = fd_data->data[1]; // 获取数据
    // 反馈数据
    fd_data->data[1] = 0x01;
    fd_data->dta_length = 2;
    allctr->can_sysback_data(fd_data);
}
void allrings_sys_w_res_rs485(struct _ALLRINGS_CTR *allctr, struct _fdcan_rxdata *fd_data)
{
    if (fd_data->data[1])
        rt_pin_write(RS485_SET_PIN, PIN_HIGH);
    else
        rt_pin_write(RS485_SET_PIN, PIN_LOW);

    // 反馈数据
    fd_data->data[1] = 0x01;
    fd_data->dta_length = 2;
    allctr->can_sysback_data(fd_data);
}
// 设备can-id
void allrings_sys_w_canid(struct _ALLRINGS_CTR *allctr, struct _fdcan_rxdata *fd_data)
{
    // uint8_t id;
    allrings_paras.allsys_para.can_id = fd_data->data[7]; // 获取到ID
    CANIO_UpdateID(allrings_paras.allsys_para.can_id);

    // 反馈数据
    fd_data->data[1] = 0x01;
    fd_data->dta_length = 2;
    allctr->can_sysback_data(fd_data);
}
// 读取fdcanindex号
void allrings_sys_r_fdcanindex(struct _ALLRINGS_CTR *allctr, struct _fdcan_rxdata *fd_data)
{
    // fd_data->data[0] = 0xFF;
    fd_data->data[1] = allrings_paras.allsys_para.canfd_broadcast_index;
    fd_data->dta_length = 2;
    allctr->can_sysback_data(fd_data);
}
// 设置fdcanindex号
void allrings_sys_w_fdcanindex(struct _ALLRINGS_CTR *allctr, struct _fdcan_rxdata *fd_data)
{
    if (fd_data->data[1] >= 0 && fd_data->data[1] <= 255)
    {
        allrings_paras.allsys_para.canfd_broadcast_index = fd_data->data[1]; // 获取index号

        fd_data->data[1] = 0x01;
        fd_data->dta_length = 2;
        allctr->can_sysback_data(fd_data);
        // 发生信号量，通知存储线程进行
        extern rt_sem_t sem_saved;
        rt_sem_release(sem_saved);
    }
}
// 读地址
void allrings_sys_r_addr(struct _ALLRINGS_CTR *allctr, struct _fdcan_rxdata *fd_data)
{
    uint8_t num = 1;
    fd_data->data[num++] = 0x12;
    fd_data->data[num++] = 0x34;
    fd_data->data[num++] = 0x56;
    fd_data->data[num++] = 0x78;
    fd_data->data[num++] = 0x00;
    fd_data->data[num++] = 0x33;
    fd_data->dta_length = num;
    allctr->can_sysback_data(fd_data);
}

// 设置boot升级状态
void allrings_sys_w_iap(struct _ALLRINGS_CTR *allctr, struct _fdcan_rxdata *fd_data)
{
    uint16_t user_data;
    user_data = fd_data->data[1] << 8 | fd_data->data[2]; // 获取设置的数据
    if (user_data == 0x2222)                              // 查询程序当前状态APP or BOOT
    {
        fd_data->data[0] = 0x98;
        fd_data->dta_length = 3;
        allctr->can_sysback_data(fd_data);
    }
    else if (user_data == 0x5508)
    {
        {
            allrings_paras.allsys_para.upgrate_flag = 0; // 设置boot升级状态标志
            // 发生信号量，通知存储线程进行
            extern rt_sem_t sem_saved;
            rt_sem_release(sem_saved);
        }
    }
}

// 清除系统错误
void allrings_sys_w_clear(struct _ALLRINGS_CTR *allctr, struct _fdcan_rxdata *fd_data)
{
    if (allrings_paras.allsys_para.rings_devices == RINGS_RS485_EPG_XX)
    {
        if (allctr->allrings_values.allsys_err.B.H & 0x20) // 如果存在使能故障
        {
            allctr->_epg_ctr_p->epg_values.epg_enable_values.epg_enable_times = 0x00;
            allctr->_epg_ctr_p->epg_values.epg_enable_values.epg_enable_err_temp = 0x01;
            allctr->_epg_ctr_p->epg_values.epg_enable_values.epg_enable_auto_finished = 0x00;
        }
    }
    allctr->allrings_values.allsys_err.Byt = 0;
    allctr->_epg_ctr_p->epg_values.epg_com_err_judge.rs485_err_failure_counter = 0;
    allctr->_epg_ctr_p->epg_values.epg_com_err_judge.rs485_err_timeout_counter = 0;

    fd_data->data[1] = 0x01;
    fd_data->dta_length = 2;
    allctr->can_sysback_data(fd_data);
}

// 读系统错误
void allrings_sys_r_err(struct _ALLRINGS_CTR *allctr, struct _fdcan_rxdata *fd_data)
{
    fd_data->data[0] = 0xFF;
    // memcpy(&fd_data->data[1], &allctr->allrings_values.allsys_err.Byt, 4);
    fd_data->data[1] = allctr->allrings_values.allsys_err.Byt >> 24;
    fd_data->data[2] = allctr->allrings_values.allsys_err.Byt >> 16;
    fd_data->data[3] = allctr->allrings_values.allsys_err.Byt >> 8;
    fd_data->data[4] = allctr->allrings_values.allsys_err.Byt & 0xff;
    fd_data->dta_length = 5;
    allctr->can_sysback_data(fd_data);
}

void allrings_sys_w_canres(struct _ALLRINGS_CTR *allctr, struct _fdcan_rxdata *fd_data)
{
    if (fd_data->data[1] == 0x00 || fd_data->data[1] == 0x01)
    {
        if (fd_data->data[1] == 0x01)
        {
            CAN_REN_EN();
            allctr->allrings_values.can_res_sta = 0x01;
        }
        else
        {
            CAN_REN_DISEN();
            allctr->allrings_values.can_res_sta = 0x00;
        }
        fd_data->data[1] = 0x01; // 成功
    }
    else
        fd_data->data[1] = 0x00; // 失败

    fd_data->dta_length = 2;
    allctr->can_sysback_data(fd_data);
}

void allrings_sys_r_canres(struct _ALLRINGS_CTR *allctr, struct _fdcan_rxdata *fd_data)
{
    fd_data->data[0] = ALLRINGS_SYS_READ_CAN_RES;
    fd_data->data[1] = allctr->allrings_values.can_res_sta;
    fd_data->dta_length = 2;
    allctr->can_sysback_data(fd_data);
}

void allrings_sys_w_485res(struct _ALLRINGS_CTR *allctr, struct _fdcan_rxdata *fd_data)
{
    if (fd_data->data[1] == 0x00 || fd_data->data[1] == 0x01)
    {
        if (fd_data->data[1] == 0x01)
        {
            RS485_REN_EN();
            allctr->allrings_values.rs485_res_sta = 0x01;
        }
        else
        {
            RS485_REN_DISEN();
            allctr->allrings_values.rs485_res_sta = 0x00;
        }
        fd_data->data[1] = 0x01; // 成功
    }
    else
        fd_data->data[1] = 0x00; // 失败

    fd_data->dta_length = 2;
    allctr->can_sysback_data(fd_data);
}

void allrings_sys_r_485res(struct _ALLRINGS_CTR *allctr, struct _fdcan_rxdata *fd_data)
{
    fd_data->data[1] = allctr->allrings_values.rs485_res_sta;
    fd_data->dta_length = 2;
    allctr->can_sysback_data(fd_data);
}
